<template>
    <div v-if="!_remote">
        <el-empty :image-size="200" />
    </div>
    <div v-if="_remote" class="remote-summary-panel">
        <div class="remote-title-bar">
            <div class="remote-title">{{ _remote.name }}</div>
            <div v-if="_remote && _remote.host != '127.0.0.1'" class="remote-title-btn">
                <el-button v-if="!_env_installed" type="danger" plain @click="onRemoteInstall" :loading="_installing">{{ _installing ? '部署中' : '一键部署' }}</el-button>
                <el-button v-if="_env_installed && !_need_update" type="info" plain disabled>已部署</el-button>
                <el-button v-if="_env_installed && _need_update" type="danger" plain @click="onRemoteInstall" :loading="_installing">{{
                    _installing ? '升级中' : '升级服务'
                }}</el-button>
                <el-button v-if="!_app_started" :type="_env_installed ? 'danger' : 'info'" plain @click.stop.prevent="onStartServer" :disabled="!_env_installed || _installing"
                    >启动服务</el-button
                >
                <el-button v-if="_app_started" type="danger" plain @click.stop.prevent="onStopServer" :disabled="_installing">停止服务</el-button>
            </div>
        </div>
        <div v-if="_remote && _remote.host != '127.0.0.1'" class="remote-script-cmd">远程执行： {{ _current_command }}</div>
        <div class="remote-env-panel">
            <div class="remote-env-block">
                <div class="remote-env-title">机器配置</div>
                <div class="remote-env-infos">
                    <div v-for="(env, index) in _machine_infos" class="remote-env-list">
                        <div class="remote-env-list-key">{{ env.key }}</div>
                        <div class="remote-env-list-value">{{ env.value }}</div>
                    </div>
                </div>
            </div>
            <div class="remote-env-block">
                <div class="remote-env-title">系统信息</div>
                <div class="remote-env-infos">
                    <div v-for="(env, index) in _system_infos" class="remote-env-list">
                        <div class="remote-env-list-key">{{ env.key }}</div>
                        <div class="remote-env-list-value">{{ env.value }}</div>
                    </div>
                </div>
            </div>
        </div>
        <div class="conda-infos-block">
            <el-button class="conda-env-new" type="primary" plain size="small" @click.stop="showDialog(true)">新建</el-button>
            <div class="conda-env-title">conda环境列表</div>
            <div class="conda-infos">
                <el-collapse v-model="_active_envs" class="conda-envs-collapse" @change="handleCollapse">
                    <el-collapse-item v-for="(env, index) in _conda_envs" :key="index" :name="index.toString()">
                        <template #title>
                            <div class="collapse-item-title">
                                <span>{{ env.name }}</span>
                                <span>{{ env.path }}</span>
                            </div>
                        </template>
                        <div class="conda-env-packs">
                            <el-skeleton v-if="!_conda_envs_detail[index]" :rows="5" animated class="skeleton-conda-envs" />
                            <el-table v-if="_conda_envs_detail[index]" :data="_conda_envs_detail[index]" highlight-current-row class="centered-table">
                                <el-table-column prop="name" label="name" width="250px" />
                                <el-table-column prop="version" label="version" width="250px" />
                            </el-table>
                        </div>
                    </el-collapse-item>
                </el-collapse>
            </div>
        </div>
    </div>
    <!-- config model dialog -->
    <el-dialog v-model="_dialogFormVisible" title="Conda环境" align-center width="500px" :before-close="handleBeforeClose">
        <div class="dlg-conda-env-panel">
            <div class="dlg-conda-env-title">选择安装环境</div>
            <el-select class="dlg-conda-env-selector" v-model="_conda_env" placeholder="选择conda环境" style="width: 240px">
                <el-option v-for="env in _conda_env_list" :key="env.name" :label="env.name" :value="env.name">
                    <span style="float: left">{{ env.name }}</span>
                    <span style="float: right; color: var(--el-text-color-secondary); font-size: 13px">{{ env.desc }}</span>
                </el-option>
            </el-select>
        </div>
        <template #footer>
            <span class="dialog-footer">
                <el-button type="primary" @click="onCondaEnvNew">确 定</el-button>
                <el-button @click="showDialog(false)">取 消</el-button>
            </span>
        </template>
    </el-dialog>
</template>

<script setup>
import API from '@/js/api';
import { ref, onMounted, getCurrentInstance, inject, nextTick } from 'vue';
import { ElLoading, ElMessage } from 'element-plus';

// 定义导出函数和事件
let vueApp = inject('vueApp');
const { proxy } = getCurrentInstance();
const emit = defineEmits(['updateSshStatus']);
defineExpose({ setRemote, setCmdStart });

// 机器信息的展示
const _remote = ref(null);
const _machine_infos = ref([]);
const _system_infos = ref([]);
const _env_installed = ref(false);
const _app_started = ref(false);
const _need_update = ref(false);
const _install_version = ref(false);
const _installing = ref(false);

// 远程正在执行的命令
const _current_command = ref('');

// 当前环境的conda信息
const _conda_envs = ref([]);
const _conda_envs_detail = ref([]);
const _active_envs = ref([]);

// conda环境对话框
let _dialogFormVisible = ref(false);
let _conda_env_list = ref(null);
let _conda_env = ref(null);

// 设置当前显示的remote或者local
async function setRemote(remote) {
    // console.log('Remote summary tab setRemote = ', remote);
    let loading = ElLoading.service({
        lock: true,
        text: '加载中...',
        background: 'rgba(0, 0, 0, 0.7)'
    });

    // 获取本地或者远程系统信息
    let result = null;
    if (remote == 'local') {
        loading.setText('加载本地系统信息...');
        result = await API.local.invoke('LocalSystemInfo', {});

        // console.log(result);
        if (result.code == 0) {
            _remote.value = {
                id: 'local',
                name: '本地机器',
                host: '127.0.0.1',
                port: '3000'
            };
            parseSystemInfos(JSON.parse(result.msg));
            loading.setText('激活本地环境...');
            await setLocalProvider();
        }
    } else {
        // 获取远程机器信息和系统信息
        loading.setText(`加载远程${remote.name}系统信息...`);
        result = await API.local.invoke('RemoteSystemInfo', {
            remoteId: remote.id
        });
        console.log('RemoteSystemInfo result = ', result);
        if (result.code == 0) {
            _remote.value = remote;
            parseSystemInfos(JSON.parse(result.msg));

            // 判断labelapp是否已经启动，如果已经启动切换运行环境
            if (_app_started.value) {
                loading.setText(`激活远程环境${remote.name}`);
                await setRemoteProvider(remote);
            }
        } else {
            // ElMessage.error('加载远程信息失败！');
            await setLocalProvider();
            emit('updateSshStatus', remote.id);
        }
    }

    // 关闭加载动画
    loading.close();
}

async function handleCollapse(val) {
    // console.log(val);
    let active_indexs = val.map((item) => {
        return parseInt(item);
    });
    for (let i = 0; i < active_indexs.length; i++) {
        let env_index = active_indexs[i];
        if (!_conda_envs_detail.value[env_index]) {
            let env_name = _conda_envs.value[env_index].name;
            let details = await getCondaDetails(env_name);
            _conda_envs_detail.value[env_index] = details;
        }
    }
}

function setCmdStart(cmd) {
    _current_command.value = cmd;
}

// 比较笨的方法读取并展示信息
function parseSystemInfos(system_infos) {
    // 解析系统配置信息
    let infos = [];
    infos.push({
        key: 'CPU架构',
        value: system_infos['architecture']
    });
    infos.push({
        key: 'CPU型号',
        value: system_infos['cpuInfo']['cpuModel']
    });
    infos.push({
        key: 'CPU核数',
        value: system_infos['cpuInfo']['cpuCores']
    });
    infos.push({
        key: '内存容量',
        value: system_infos['memoryInfo']['total']
    });
    infos.push({
        key: '存储空间',
        value: system_infos['diskInfo']['totalSize']
    });
    infos.push({
        key: '使用空间',
        value: `${system_infos['diskInfo']['totalUsed']} (${system_infos['diskInfo']['percent']})`
    });
    let gpuInfo = system_infos['gpuInfo'];
    let gpuInfoStr = 'null';
    if (gpuInfo.length > 0) {
        let gpuType = `${system_infos['gpuInfo'][0]['name']}`;
        if (gpuInfo.length > 1) {
            gpuInfoStr = `[${gpuType}] x ${gpuInfo.length}`;
        } else {
            gpuInfoStr = gpuType;
        }
    }

    infos.push({
        key: 'GPU信息',
        value: gpuInfoStr
    });
    _machine_infos.value = infos;

    // 解析软件配置信息
    infos = [];
    infos.push({
        key: 'OS',
        value: system_infos['osInfo']
    });
    infos.push({
        key: 'CUDA',
        value: `nvidia-smi:${system_infos['cudaInfo']['nvidiaSmiCUDA']} | nvcc:${system_infos['cudaInfo']['nvccVersion']}`
    });
    infos.push({
        key: 'CuDNN',
        value: system_infos['cuDnnInfo']['version']
    });
    let softwares = ['conda', 'node', 'python', 'labelapp'];
    for (let i = 0; i < softwares.length; i++) {
        let key = softwares[i];
        infos.push({
            key: key,
            value: system_infos['software'][key] ? system_infos['software'][key]['version'] : 'null'
        });
    }

    // 更新conda环境列表
    _conda_envs.value = system_infos['condaEnvs'];
    _conda_envs_detail.value = system_infos['condaEnvs'].map((item) => {
        return null;
    });

    // 判断环境是否已经安装完全，主要还是服务环境
    _env_installed.value = system_infos['software']['conda'] && system_infos['software']['node'] && system_infos['software']['labelapp'];
    _system_infos.value = infos;
    if (_remote.value && _remote.value.host != '127.0.0.1') {
        _install_version.value = system_infos['software']['labelapp'] ? system_infos['software']['labelapp'].version : 'null';
    }

    // 获取labelapp的信息，包括状态和版本
    _app_started.value = system_infos.labelapp && system_infos.labelapp.status == 'running' ? true : false;
    let newVersion = system_infos.labelapp && system_infos.labelapp.newVersion;
    _install_version.value = system_infos.labelapp && system_infos.labelapp.installVersion;
    console.log('最新版本:', newVersion);
    console.log('安装版本:', _install_version.value);
    if (_install_version.value !== newVersion && _install_version.value != null) {
        _need_update.value = true;
    } else {
        _need_update.value = false;
    }
}

// 安装远程服务基础环境（conda、node、server）
async function onRemoteInstall() {
    // 执行远程安装部署脚本
    _installing.value = true;
    let result = await API.local.invoke('RemoteInstall', {
        remoteId: _remote.value.id
    });
    console.log(result);

    // 读取最新的系统信息
    result = await API.local.invoke('RemoteSystemInfo', {
        remoteId: _remote.value.id
    });
    // console.log(result);
    if (result.code == 0) {
        parseSystemInfos(JSON.parse(result.msg));
    }
    _installing.value = false;
}

// 启动远程的labelapp服务
async function onStartServer() {
    let result = await API.local.invoke('RemoteAppController', {
        remoteId: _remote.value.id,
        operation: 'start'
    });

    // 判断服务是否启动，根据结果切换环境
    _app_started.value = result.code == 0 ? true : false;
    switchEnvironment(_app_started.value);
}

// 关闭远程的labelapp服务
async function onStopServer() {
    let result = await API.local.invoke('RemoteAppController', {
        remoteId: _remote.value.id,
        operation: 'stop'
    });
    console.log(result);

    // 判断服务是否启动，根据结果切换环境
    _app_started.value = result.code == 0 ? false : true;
    switchEnvironment(_app_started.value);
}

async function setLocalProvider() {
    let provider = API.getProvider();
    if (provider != 'Local') {
        await API.setProvider(`local`);
        vueApp.setMachine('Local');
        ElNotification({
            title: '提示',
            message: `环境已经切换到本地！`,
            type: 'info',
            duration: 1500,
            border: true
        });
    }
}

async function setRemoteProvider(remote) {
    let provider = API.getProvider();
    console.log(`provider = ${provider}, remote = `, remote);
    if (provider.startsWith('Remote:')) {
        provider = provider.replace(/^Remote:/, '');
        if (provider == remote.name) {
            return;
        }
    }

    await API.setProvider(`remote:${remote.id}`);
    vueApp.setMachine(remote.name);
    ElNotification({
        title: '提示',
        message: `环境切换到远程${remote.name}`,
        type: 'info',
        duration: 1500,
        border: true
    });
}

async function switchEnvironment(server_started) {
    if (server_started) {
        await setRemoteProvider(_remote.value);
    } else {
        await setLocalProvider();
    }
}

async function getCondaList() {
    let result = await API.local.invoke('CondaEnvList', {
        remoteId: _remote.value.id
    });
    // console.log(result);
    if (result.code == 0) {
        _conda_envs.value = result.msg;
        _conda_envs_detail.value = result.msg.map((item) => {
            return null;
        });
    }
}

async function getCondaDetails(env) {
    let result = await API.local.invoke('CondaEnvDetails', {
        remoteId: _remote.value.id,
        env: env
    });

    // console.log(result);
    if (result.code == 0) {
        return result.msg;
    } else {
        return null;
    }
}

async function onCondaEnvNew() {
    if (!_conda_env.value) {
        ElMessage.error('环境名称不能为空！');
        return;
    }

    let ifexisted = _conda_envs.value.find((item) => {
        return item.name == _conda_env.value;
    });
    if (ifexisted) {
        ElMessage.error(`conda环境已经存在${_conda_env.value}`);
        return;
    }

    // 关闭对话框
    showDialog(false);

    // 查找conda环境信息
    console.log(`onCondaEnvNew envName = `, _conda_env.value);
    const env = _conda_env_list.value.find((item) => {
        return item.name == _conda_env.value;
    });
    console.log(env);

    // 安装conda环境
    let result = await API.local.invoke('CondaEnvNew', {
        remoteId: _remote.value.id,
        envName: env.name,
        envPath: env.path
    });
    console.log(result);

    // 重新更新列表
    await getCondaList();
}

async function showDialog(show) {
    if (_conda_env_list.value == null) {
        let result = await API.invoke('CondaEnvServer', { method: 'list' });
        if (result.code == 0) {
            _conda_env_list.value = result.msg;
        }
    }
    _dialogFormVisible.value = show;
    vueApp.monitorKeyEvent(!show);
}

function handleBeforeClose(done) {
    vueApp.monitorKeyEvent(true);
    done();
}

onMounted(() => {});
</script>

<style scoped>
.remote-title-bar {
    display: flex;
    justify-content: space-between;
    padding: 10px 10px 0px 10px;
}

.remote-title {
    font-size: 22px;
    font-weight: 600;
}

/* .remote-title-btn {} */
.remote-subtitle-line {
    margin: 5px 10px;
    display: flex;
    justify-content: space-between;
}

.remote-subtitle {
    font-size: 16px;
    font-weight: 500;
    color: gray;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.remote-script-cmd {
    margin: 10px 5px 2px 5px;
    border-radius: 4px;
    padding: 2px 2px 3px 10px;
    background-color: black;
    width: 100%;
    color: #e9e9e9;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.remote-env-panel {
    display: flex;
    width: 100%;
}

.remote-env-block {
    width: 50%;
    box-shadow: 2px 2px rgba(193, 193, 241, 0.5);
    background-color: #e9e9e9;
    margin: 10px 5px;
    padding: 2px 3px 3px 2px;
}

.remote-env-title {
    font-weight: 700;
    text-align: center;
    margin: 5px;
}

.remote-env-infos {
    background-color: white;
    padding: 10px 5px 5px 5px;
    box-shadow: inset 3px 3px rgb(223, 223, 223);
    height: 240px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.remote-env-list {
    display: flex;
    justify-content: space-between;
    padding: 5px;
    font-family: Arial, 'Microsoft YaHei', sans-serif;
    line-height: 1.5;
}

.remote-env-list-key {
    flex: 0 0 70px;
    margin-left: 5px;
}

.remote-env-list-value {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.remote-summary-panel {
    width: 100%;
    height: 100%;
}

.conda-infos-block {
    position: relative;
    box-shadow: 2px 2px rgba(193, 193, 241, 0.5);
    background-color: #e9e9e9;
    margin: 10px 5px;
    padding: 10px 2px 5px 2px;
    box-sizing: border-box;
}

.conda-env-title {
    font-weight: 700;
    margin: 0px 0px 10px 0px;
    text-align: center;
    box-sizing: border-box;
}

.conda-env-new {
    position: absolute;
    top: 10px;
    right: 10px;
}

.conda-infos {
    margin: 4px;
    background-color: white;
}

.conda-envs-collapse {
    padding-left: 10px;
}

.conda-envs-collapse :deep(.el-collapse-item__header) {
    font-size: 16px;
    font-weight: 500;
}

.conda-env-path {
    font-size: 14px;
}

.conda-env-packs {
    display: flex;
    justify-content: center;
    background-color: aliceblue;
    padding: 5px;
    box-sizing: border-box;
}

.collapse-item-title {
    display: flex;
    justify-content: space-between;
    width: calc(100% - 40px);
}

.centered-table {
    width: 500px;
}

.skeleton-conda-envs {
    width: 100%;
    padding: 20px;
}

.dlg-conda-env-panel {
    display: flex;
}

.dlg-conda-env-title {
    padding: 5px;
}

.dlg-conda-env-selector {
    flex: 1;
    margin-left: 5px;
}
</style>
